<?php
/**
 * Created by PhpStorm.
 * User: zd
 * Date: 2018/10/31
 * Time: 15:59
 */

namespace app\api\service;

use app\api\model\CardBase;
use app\api\model\CardBrowse;
use app\api\model\CardExtend;
use app\api\model\CardProduct;
use app\api\model\CardTag;
use app\api\model\CardThumbsup;
use app\api\model\PosterUser;
use app\api\model\ThirdApp;
use app\api\model\Poster;
use app\api\model\User;
use app\api\model\UserWorkuser;
use app\api\model\WebSubelement;
use app\api\model\WorkUser;
use app\common\lib\Redis;
use app\common\lib\Socket;
use app\lib\exception\MiniSuiteException;
use think\Cache;
use think\Config;
use think\Loader;

Loader::import('MiniDecrypt.wxBizDataCrypt',EXTEND_PATH);
class Card
{
    /**
     * 获取二维码
     * @param $wu_id
     * @return string
     * @throws MiniSuiteException
     */
    public function getQRCode($wu_id){
        $user = WorkUser::getUserByWuID($wu_id);
        $t_id = $user->t_id;
        if ($user->ai_power == 'off'){
            throw new MiniSuiteException([
                'code'=>'201',
                'msg'=>'未开通名片',
                'error_code'=>'999'
            ]);
        }
        //已有名片直接返回
        if (null != $user->qr_code){
            return $user->qr_code;
        }
       //获取名片码
        $scene = 'qrcode_' . $wu_id;
        $page = 'pages/card/card';
        list($data, $path, $name, $result) = $this->getQRCodeImg( $t_id,$wu_id,$scene,$page);
        if ($data != null || !$result){
            throw new MiniSuiteException([
                'code'=>'201',
                'msg'=>'获取二维码'.$data->errmsg,
                'error_code'=>$data->errcode
            ]);
        }else{
            $info['qr_code'] = $result['key'];
            WorkUser::updateUserInfo($wu_id,$info);
            return $result['key'];
        }
    }
    /**
     * 获取名片列表，第一次通过搜索进入小程序，
     * 则展示推荐名片列表。若有名片则展示已有名片
     * @param $uid
     * @return $this
     */
    public function getCardList($uid){
        $result = [];
        $manager_id = Token::getCurrentTokenVar('manager_id');
        $userInfo = User::with(['workuser'])->find($uid);
        if ($userInfo->workuser->isEmpty()){//用户搜索进入
            return $result;
        }
        $userInfo = $this->ownCardList($uid,$manager_id);//获取已有名片
        //获取用户缓存
        $result = $this->getCacheMessage($uid, $userInfo);
        return $result;
    }
    /**
     * 用户已有列表
     * @param $uid
     * @param $manager_id
     * @return $this|bool|string
     */
    public function ownCardList($uid,$manager_id){
        $tag = sprintf(config('cache.own_list'),$manager_id,$uid);
        $result =  Redis::getInstance()->get('2',$tag);
        if (!empty($result)){
            return $result;
        }
        $user = new User();
        $data  = $user->ownCardList($uid);
        Redis::getInstance()->set('2',$tag,json_encode($data),2*24*3600);
        return $data;
    }

    /**
     * 获取名片基本信息
     * @param $uid
     * @param $wu_id
     * @return array|bool|false|\PDOStatement|string|\think\Model
     * @throws \think\Exception
     */
    public function getCardInfo($uid,$wu_id){
        //异步行为处理
        $array =[ 'function'=>'insertBrowse','args'=>['user_id'=>$uid,'wu_id'=>$wu_id]];
        $task = new Socket("tcp://127.0.0.1:27000",5);
        $task->asyncTask($array);
        //id处理
        $tag = sprintf(config('cache.card_base'),$wu_id);
        //缓存的处理
        $cardInfo = Redis::getInstance()->get(1,$tag);
        if ($cardInfo){
            return $cardInfo;
        }
        $user = new User();
        $cardInfo = $user::getCardInfo($wu_id);
        $cardInfo =  $cardInfo->toArray();
        if (!empty($cardInfo)){
            Redis::getInstance()->set(1,$tag,$cardInfo,7200);
        }
        return $cardInfo;
    }

    /**
     * 获取浏览寂记录
     * @param $wu_id
     * @return null|static
     */
    public function getBrowse($wu_id){
        $browse = CardBrowse::getBrowse($wu_id);
        $info = (new CardBase())->getCardBase($wu_id);
        $num = $info->visible(['browsing_num']);
        if (!$browse->isEmpty()){
            foreach ($browse as $item){
                $item->visible(['users']);
                if ($item->users != null ){
                    $item->users->visible(['avatar_url']);
                }
            }
            $data = $browse->toArray();
            $browseInfo['user'] = $data;
            $browseInfo['num'] = $num;
        }else{
            $browseInfo['user'] = [];
            $browseInfo['num'] = $num;
        }
        return $browseInfo;
    }
    /**
     * 获取点赞量
     * @param $user_id
     * @param $w_id
     * @return mixed
     */
    public function getThumsUpNum($user_id,$w_id){
        $list = CardThumbsup::getThumbs($w_id);
        if ($list->isEmpty()){
            $data['identfy'] = 'false';
            $data['num'] = 0;
        }else{
            $array = $list->toArray();
            $ids = array_column($array,'user');
            $data['identfy'] = !in_array($user_id,$ids)?'false':'true';
            $data['num'] = sizeof($ids);
        }
        return $data;
    }
    /**
     * 获取标签列表
     * @param $w_id
     * @return false|\PDOStatement|string|\think\Collection
     */
    public function getTagList($w_id){
        $list = CardTag::getTag($w_id);
       return $list;
    }
    /**
     * 获取推荐商品
     * @param $wu_id
     * @return array
     */
    public function getCardProduct($wu_id){
        $cardProduct = new CardProduct();
        $goods = $cardProduct->getGoods($wu_id);
       foreach ($goods as $value){
           $value->visible(['w_id','goods']);
           $value->goods->visible(['id','name','price','main_img_url']);
       }
       $list =  $goods->toArray();
        foreach ($list as $key=>$value){
            $list[$key]['goods'] = $value['goods'][0];
        }
      return $list;
    }
    /**
     * 获取名片拓展信息
     * @param $uid
     * @param $wu_id
     * @return $this
     */
    public function getCardExtendInfo($wu_id){
        $tag = sprintf(config('cache.card_extend'),$wu_id);
        //缓存的处理
        $cardInfo = Redis::getInstance()->get(1,$tag);
        if ($cardInfo){
            return $cardInfo;
        }
        $user = new User();
        $cardInfo = $user::getCardExtendInfo($wu_id);
        if (!empty($cardInfo)){
            Redis::getInstance()->set(1,$tag,$cardInfo,7200);
        }
        return $cardInfo;
    }

    /**
     * 获取分享语
     * @param $wu_id
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function getShareWord($wu_id){
        $sharedWord = CardExtend::getShareWord($wu_id);
        return $sharedWord;
    }

    /**
     * 获取用户信息
     * @param $uid
     * @return null|static
     */
    public function getUserInfoById($uid){
        $info = User::getUserInfoByUid($uid);
        return $info;
    }
    /**
     *获取官网信息
     * @param $uid
     * @return mixed
     */
    public function getWebInfo($manager_id){
        $tag = sprintf(config('cache.web'),$manager_id);
        //缓存的处理
        $status = Redis::getInstance()->get(6,$tag);
        if ($status){
            return json_encode($status);
        }
        $appInfo = ThirdApp::getUserAuthInfo($manager_id);
        $web_info = $appInfo->web_info;
        Redis::getInstance()->set(6,$tag,$web_info,3600);
        return $web_info;
    }
    /**
     * 获取子元素信息
     * @param $uid
     * @param $sub_id
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function getSubWebInfo($uid,$sub_id,$type){
        $web_info = WebSubelement::getSubWeb($uid,$sub_id,$type);
        return $web_info;
    }
    /**
     * 创建父级
     * @param $uid 用户id
     * @param $wu_id 名片id
     * @param $poster 海报id(默认为0)
     * @param $source 来源
     * @param $sharer 分享人(默认为0)
     * @param $manager_id 管理员id
     * @return int
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function createFather($uid,$wu_id,$poster_id,$source,$sharer,$manager_id){
        if ($poster_id != 0){
          Poster::addBrowerNum($poster_id);//浏览次数递增
          $poster = new PosterUser();
          $result = $poster->getLog($uid,$poster_id);//获取记录
           if (empty($result)){
               $poster->addLog($uid,$poster_id);//添加记录
           }
        }
        //判断是否已添加到用户名片中间表
        $info = User::with(['workuser'])->find($uid);
        if (!$info->workuser->isEmpty()){
            foreach ($info->workuser as $workUser){
                $id[] = $workUser->id;
            }
            if (in_array($wu_id,$id)){
                return 1;
            }
        }
        $user = new User();
        $status = $user->createFather($uid,$wu_id,$source,$sharer);
        $tag = sprintf(config('cache.own_list'),$manager_id,$uid);
        Redis::getInstance()->del(2,$tag);//删掉用户已有名片列表缓存
        return $status;
    }
    /**
     * 更新用户数据
     * @param $uid
     * @param $data
     * @return bool
     * @throws \app\lib\exception\TokenException
     * @throws \think\Exception
     */
    public function updateUser($uid,$data){
        $t_id = Token::getCurrentTokenVar('manager_id');
        $rawData = json_decode($data['rawData'],true);
        $user = new User();
        $result =  $user->updateUserInfo($uid,$t_id,$rawData);
        if (!$result){
            return false;
        }
        return true;
    }
    /**
     * 更新用户信息
     * @param $uid
     * @param $t_id
     * @param $data
     * @return bool
     */
    public function updateUserInfo($uid,$t_id,$data){
        $user = new User();
        $result =  $user->updateUserInfo($uid,$t_id,$data);
        if (!$result){
            return false;
        }
        return true;
    }

    /**
     * 解密小程序获取电话号码
     * @param $w_id
     * @param $uid
     * @param $data
     * @return string
     * @throws \app\lib\exception\TokenException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getAuthorizedTelephone($w_id,$uid,$data){
        $id = explode('_',$w_id);
        $t_id = Token::getCurrentTokenVar('manager_id');
        $info = ThirdApp::getDetailUserInfoByMini($t_id);
        $appid = $info->mini->authorizer_appid;
        $encryptedData = $data['encrypdata'];
        $iv = $data['ivdata'];
        $sessionKey = Token::getCurrentTokenVar('session_key');
        $pc = new \wxBizDataCrypt($appid, $sessionKey);
        $info = $pc->decryptData($encryptedData, $iv, $data);
        if ($info == 0){
            $info = json_decode($data);
            User::updatePhone($info->purePhoneNumber,$uid);//更新用户授权电话
            UserWorkuser::updatePhone($id[1],$uid,$info->purePhoneNumber);//更新对应用户电话
            //推送行为
            $behavior = new Behavior();
            $behavior->getBehavior($uid,$id[1],'auth_phone','授权电话',$id[1]);
            return $info->purePhoneNumber;
        }else{
            return '';
        }
    }
    /**
     *
     * @param $uid
     * @param $w_id
     * @return int|true
     */
    public function clickTag($uid,$id){
        $name = 'tag_'.$uid.$id;
        if (cache($name)){
            $status = cache($name);
            return $status;
        }
        $tag = new CardTag();
        $status = $tag->clickTag($id);
        $expire_in = 24*60*60;//过期时间
        cache($name,$status,$expire_in);
        return $status;
    }

    /**
     * 获取access_token
     * @param $uid
     * @return bool|mixed
     * @throws MiniSuiteException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function getAcessToken($uid){
        $info = ThirdApp::getDetailUserInfoByMini($uid);
        $appid = $info->mini->authorizer_appid;
        if (cache($appid)){
            $access_token = json_decode(cache($appid));
        }else{
            $mini = new Mini();
            $access_token =  $mini->getAccessToken($appid);
        }
        return $access_token;
    }

    /**
     * 创建文件夹
     * @return string
     */
    private function createFolder(){
        $data =  date('Ymd',time());
        $path = './qrcode/'.$data;
        if (!is_dir($path)){
            mkdir('./qrcode/'.$data,0777);
        }
        return $path;
    }

    /**
     * 获取二位码图片
     * @param $t_id
     * @param $scene
     * @param $page
     * @return array
     * @throws \Exception
     */
    public function getQRCodeImg($t_id,$wu_id,$scene,$page): array
    {
        $access_token = $this->getAcessToken($t_id);
        $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s';
        $url = sprintf($url, $access_token);
        $params = [
            "scene" =>$scene,
            "page" => $page,
        ];
        $requestData = curl_post($url, $params);
        $data = json_decode($requestData);
        $path = $this->createFolder();
        $name = md5(time() + rand(0, 1000));
        $result = file_put_contents($path . '/' . $name . '.jpg', $requestData, true);
        if ($result){
            $uplode = new FileUpload();//7牛云上传
            $result =  $uplode->uploadFile(ltrim($path.'/'.$name.'.jpg', "."),$path . '/' . $name . '.jpg',$wu_id);
        }
        return array($data, $path, $name, $result);
    }
    /**
     * 获取用户缓存信息
     * @param $uid
     * @param $userInfo
     * @param $message
     * @return mixed
     */
    public function getCacheMessage($uid, $userInfo)
    {
        try {
            $cache = Cache::connect(Config::get('cache.redis'));
            foreach ($userInfo['workuser'] as $key => $item) {
                //获取用户未读消息
                $userInfo['workuser'][$key]['unread'] = $this->getUnreadList($cache->handler(), $item['id'], $uid);
            }
            return $userInfo;
        } catch (\Exception $exception) {
            //报错和消息通知
            return $userInfo;
        }
    }
    /**
     * 获取用户未读消息条数
     * @param $handler
     * @param $wu_id
     * @param $uid
     * @return int|string
     */
    public function getUnreadList($handler,$wu_id,$uid){
        $i = 0;
        $list =  $handler->zRange("message:wid:".$wu_id.":unread:user:".$uid.":list:2",0,-1);
        if (empty($list)){
            return $i;
        }
        foreach ($list as $item){
            $data = json_decode($item,true);
            if ($data['user_type'] == 2){
                $i++;
            }
        }
        return $i;
    }
}
